package com.virtualightning.mvvm.tools

import java.io.Closeable

/**
 *  Anchor : Create by CimZzz
 *  Time : 2021/11/06 19:37
 *  结果 Future
 */
class ResultFuture<T>(
	/**
	 * 结果
	 */
	private var result: T? = null,

	/**
	 * 异常
	 */
	private var exception: Throwable? = null
): Closeable {

	/**
	 * 接收结果
	 * @param result T 结果
	 */
	fun accept(result: T) {
		synchronized(this) {
			if(exception != null || this.result != null) {
				return
			}
			this.result = result
			(this as Object).notifyAll()
		}
	}

	/**
	 * 接收异常
	 * @param exception Throwable 异常
	 */
	fun accept(exception: Throwable) {
		synchronized(this) {
			if(this.exception != null || result != null) {
				return
			}
			this.exception = exception
			(this as Object).notifyAll()
		}
	}

	/**
	 * 阻塞线程获取结果
	 * @return T 结果
	 */
	fun await(): T {
		synchronized(this) {
			val exception = exception
			if(exception != null) {
				throw exception
			}
			val result = result
			if(result == null) {
				(this as Object).wait()
			}
			else {
				return result
			}
		}
		val result = this.result
		if(result != null) {
			return result
		}
		throw exception ?: RuntimeException("unknown exception")
	}

	/**
	 * 获取 Exception
	 * @return Throwable? 如果不存在返回 null
	 */
	fun getExceptionOrNull(): Throwable? {
		return exception
	}

	/**
	 * 实现 Closable 接口，关闭 Future
	 */
	override fun close() {
		synchronized(this) {
			if(result == null) {
				exception = RuntimeException("canceled")
			}
			(this as Object).notifyAll()
		}
	}
}